package socket

import (
	"errors"
	"io"
	"net"
	"servermg/log"
	"servermg/protocol"
)

const (
	ERROR_NULL_ADDR = "addr is null"
)

type SocketEvts interface {
	OnClose()
	OnConnected()
	OnPacketComplete()
}

type SocketHander struct {
	conn *net.TCPConn
	ip   string
	port int
	addr *net.TCPAddr
}

func Connect(addr string) *SocketHander {
	handler := new(SocketHander)
	handler.SetAddr(addr)
	if handler.Connect() == nil {
		return handler
	}
	return nil
}

func (this *SocketHander) SetAddr(addr string) (err error) {
	this.addr, err = net.ResolveTCPAddr("tcp4", addr)
	return err
}

func (this *SocketHander) Connect() (err error) {
	if this.addr == nil {
		return errors.New(ERROR_NULL_ADDR)
	}
	this.conn, err = net.DialTCP("tcp", nil, this.addr)
	return err
}

func (this *SocketHander) SendPacket(packet *protocol.BoyaaPacket) {
	log.Debug("send packet :", packet.Data())
	this.conn.Write(packet.Data())
}

func (this *SocketHander) Receiver() *protocol.BoyaaPacket {
	buffer := make([]byte, 2048)

	n, err := this.conn.Read(buffer)
	switch err {
	case nil:
		return Decode(buffer[:n])
	case io.EOF:
		log.Debug("Warning: End of data: %s \n", err)
		return nil
	default:
		log.Debug("Error: Reading data: %s \n", err)
		return nil

	}

}

func (this *SocketHander) Close() error {
	if this.conn == nil {
		return errors.New(ERROR_NULL_ADDR)
	}

	err := this.conn.Close()
	this.conn = nil
	return err
}

func Decode(buf []byte) *protocol.BoyaaPacket {
	pkg := new(protocol.BoyaaPacket)
	pkg.Packet(buf)

	return pkg
}
